﻿using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using RAP.Framework.Libary.Utils;
using RAP.Web.Libary.Common.Model;
using RAP.Web.Libary.Common.Model.Session;
using RAP.Web.Libary.Controller;
using System;
using System.Collections;

namespace RAP.Web.Libary.Authentication.Attributes
{
    /// <summary>
    /// 判断当前用户是否拥有指定编码的数据权限
    /// </summary>
    public class HasDataPowerAttribute : Attribute
    {
        private static IDictionary _attibutesCache = new Hashtable();

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static bool? ProcessAttributes ( ActionExecutingContext context )
        {
            var actionMethod = ( context.ActionDescriptor as ControllerActionDescriptor ).MethodInfo;
            var actionKey = $"{actionMethod.DeclaringType.FullName}.{actionMethod.Name}";
            var controller = context.Controller as IWebController;
            var queryParams = controller.QueryParams as IAPIQueryParams;
            var cityCode = queryParams.CityCode;
            if ( cityCode.IsNullOrEmpty() )
            {
                return null;
            }
            var userSession = queryParams.UserSession as IWebUserSession;
            if ( userSession == null )
            {
                return null;
            }
            var codeObj = _attibutesCache[ actionKey ];
            if ( codeObj.IsNotNullOrEmpty() )
            {
                return userSession.HasDataPower( codeObj.ToString() );
            }
            if ( codeObj == null )
            {
                var attr = actionMethod.GetCustomAttributes<HasDataPowerAttribute>().FirstItem();
                if ( attr == null )
                {
                    attr = controller.GetType().GetCustomAttributes<HasDataPowerAttribute>().FirstItem();
                }
            }
            var dataCode = codeObj != null ? codeObj.ToString() : null;
            if ( dataCode.IsNotNullOrEmpty() )
            {
                _attibutesCache[ actionKey ] = dataCode;
                return userSession.HasDataPower( $"{cityCode}.{dataCode}" );
            }
            return null;
        }
    }
}
